package com.caipiao.lottery.task.keepline;

import com.caipiao.lottery.config.Config;
import com.caipiao.lottery.dbwarpper.P_API_TASK;
import com.caipiao.lottery.log.TraceLogger;
import com.caipiao.lottery.task.TaskStatus;
import com.caipiao.lottery.task.TaskThread;
import com.caipiao.lottery.task.keepline.danmu.CookieUtile;
import com.caipiao.util.IdMaker;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.slf4j.Logger;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

/**
 * 保持cookie在线的机制
 */
public class KeepLineThread extends Thread implements TaskThread
{
    private static final String TaskName = "KeepLineThread";

    //非线程安全
    private ArrayList<CookieItem> taskList = new ArrayList<CookieItem>();

    private int m_ReadInterval;
    private int m_ProcInterval;
    private String m_ReadCount;

    private Logger logger =null;
    private String Name = "";

    private TaskStatus status = new TaskStatus();

    @Override
    public TaskStatus GetTaskStatus()
    {
        return status;
    }

    public KeepLineThread(String Name, int ReadInterval, int ReadCount, int ProcInterval, Logger logger)
    {
        m_ReadInterval = ReadInterval;
        m_ReadCount = String.valueOf(ReadCount);
        m_ProcInterval =ProcInterval;

        this.Name = Name;

        this.logger = logger;
        if (null == logger)
        {
            this.logger = TraceLogger.Task;
        }

        status.Name = Name;
        status.ThrdName = TaskName;
        status.Interval = ReadInterval;
    }

    void ReadTask() throws Exception {
        if (taskList.isEmpty()) {
            //判断执行时间
            if(!new SimpleDateFormat("HH").format(new Date()).equalsIgnoreCase("06")){
                return;
            }
            ArrayList<CookieItem> cookieList = new ArrayList<CookieItem>();
            String msgId = IdMaker.Get_DB_Id();
            //查询超时日期点
            Calendar nowDate = Calendar.getInstance();
            String expireDateStr = Config.Task.GetPropValue("KeepLine.expireHour", Name);
            nowDate.add(Calendar.HOUR_OF_DAY, Integer.parseInt(expireDateStr));
            String expireDate = new SimpleDateFormat("yyyyMMddHHmmss").format(nowDate.getTime());

            boolean db_r = P_API_TASK.findCookieList(msgId,
                    this.m_ReadCount, expireDate, cookieList);

            this.logger.debug(msgId + " - " + TaskName + " P_API_TASK.findCookieList，查询数据");

            if (!db_r) {
                throw new Exception("数据库调用  P_API_TASK.findCookieList失败");
            }
            this.logger.debug(msgId + " - " + TaskName + "保持在线:" + cookieList.size() + "条");

            if (!cookieList.isEmpty()) {
                for (CookieItem item : cookieList) {
                    this.logger.debug(msgId + " - " + TaskName + "读取cookie列表任务:|"
                            + item.userName+"-"+item.type);
                }

                taskList.addAll(cookieList);
            }
        }
    }

    private CookieItem GetCookieItem()
    {
        if (taskList.size() > 0) {
            CookieItem item = taskList.get(0);
            this.logger.debug(item.msgId + "-" + TaskName + "读取cookie数据1条成功");
            taskList.remove(0);
            return item;
        }
        this.logger.debug(TaskName + "读取cookie数据,taskList，暂无数据！");
        return null;
    }

    @Override
    public void run()
    {
        this.logger.info(this.Name + " " + TaskName + "开始 - " +
                " |ReadCount:" + m_ReadCount +
                " |ProcInterval:" + m_ProcInterval +
                " |ReadInterval:" + m_ReadInterval);
        //循环处理
        while (true) {
            boolean deal_r = true;
            WebDriver driver = null;
            if(taskList.size() > 0){
                driver = CookieUtile.Instance().getDriver();
            }
            while(taskList.size() > 0) {
                CookieItem item = this.GetCookieItem();
                this.logger.debug(item.msgId + " - " + TaskName + "开始处理cooike["+item.userName+"-"+item.type+"]");
                try
                {
                    if (item != null)
                    {
                        boolean result = ProcChartData(driver, item);
                        this.logger.debug(item.msgId + " - " + TaskName
                                + "处理cooike["+item.userName+"-"+item.type+"]，结果："+result);
                        if (result)
                        {
                            status.AddSuccess();
                        }
                        else
                        {
                            status.AddFailed();
                            deal_r = false;
                        }
                    }
                    Thread.sleep(this.m_ProcInterval);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    status.AddFailed();
                    deal_r = false;

                    this.logger.error(this.Name + " " + TaskName + " 执行异常:" + e.toString() + " - " +item.userName+"-"+item.type);

                    try
                    {
                        Thread.sleep(this.m_ProcInterval);
                    }
                    catch (InterruptedException e1)
                    {
                        e1.printStackTrace();
                    }
                }
                this.logger.debug(item.msgId + " - " + TaskName + "处理cooike["+item.userName+"-"+item.type+"]，完成");
            }

            if(null != driver){
                driver.close();
                CookieUtile.Instance().clearDriver();
            }

            status.AddInterval();

            try
            {
                if (!deal_r)
                {
                    Thread.sleep(m_ReadInterval);
                }

                //读取任务
                ReadTask();

                if (taskList.size() == 0)	//无数据
                {
                    Thread.sleep(m_ReadInterval);
                }
            }
            catch(Exception e)
            {
                this.logger.error(this.Name + " " + TaskName  + "读取数据异常:"+e.toString(), e);
                try
                {
                    Thread.sleep(m_ReadInterval);
                }
                catch (InterruptedException e1)
                {
                }
            }
        }
    }

    /**
     * 在线处理
     * @param item
     * @return
     * @throws Exception
     */
    private boolean ProcChartData(WebDriver driver, CookieItem item) throws Exception {
        String msgId = item.msgId;
        TraceLogger.Task.info(msgId + "-单次在线，开始处理[" + item.userName + "-" + item.type + "]！");
        String url = Config.Task.GetPropValue("KeepLine.url."+item.type, Name);
        ArrayList<String> arr = new ArrayList<String>();
        String cookieStr = item.cookie.replaceAll(" ", "");

        driver.get(url);
        driver.manage().deleteAllCookies();

        String[] cos = cookieStr.split(";");
        for(String co: cos){
            Cookie cookie = new Cookie(co.split("=")[0], co.split("=", -1)[1]);
            driver.manage().addCookie(cookie);
        }
        Thread.sleep(1000);
        driver.navigate().refresh();
        Thread.sleep(5000);
        //回写最后执行时间
        String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        boolean db_r = P_API_TASK.prUpdateLastRunTime(msgId, item.id, dateStr);

        this.logger.debug(msgId + " - " + TaskName + " P_API_TASK.prUpdateLastRunTime 查询数据");

        if (!db_r) {
            throw new Exception("数据库调用  P_API_TASK.prUpdateLastRunTime失败");
        }
        TraceLogger.Task.info(msgId + "-单次在线[" + item.userName + "-" + item.type + "]更新用户数据成功！");
//        driver.close();
        return true;
    }
}
